<?php

namespace App\Api\Sms;

use Illuminate\Support\Facades\Http;
use Monolog\Formatter\LineFormatter;
use Monolog\Handler\RotatingFileHandler;
use Monolog\Logger;

class Shlianlu extends Base
{
    protected $values = array();
//    企业id
    const MchId = "1039475";
//    签名
    const SignName = "联通号卡";
//    签名id
    const SignId = "92824";
    private $smsType = 1;
    private $config = [
//    根据'smsType' => [1 => '验证码', 2 => '通知', 3 => '营销'],分开配置
//    通知/验证码短信
        1 => [
            "AppId" => "10011704945091154",
            "Key" => "1b0409fdcbee4c9da72c97940e8d068a"
        ],
//    营销
        3 => [
            "AppId" => "10021704945091901",
            "Key" => "0987e212a6824a66bd1717fb2496e441"
        ]
    ];

    public function __construct($smsType = 1)
    {
        $this->smsType = $smsType;

        $this->values['MchId'] = self::MchId;
        $this->values['TimeStamp'] = $this->getMillisecond();
        $this->values['Version'] = "1.1.0";
        $this->values['SignType'] = "MD5";
        $this->root = new Logger('ShlianluSmsLog');
        $this->root->pushHandler(
            (new RotatingFileHandler(storage_path('/logs/ShlianluSmsLog.log'), 7, Logger::DEBUG, true, 0777))->setFormatter(new LineFormatter(null, null, true, true))
        );
    }

    /**
     * 设置签名，详见签名生成算法
     * @return string
     */
    public function setSign()
    {
        $sign = $this->sign();
        $this->values['Signature'] = $sign;
        return $sign;
    }

    /**
     * 生成签名
     * @param $timestamp
     * @return string
     */
    private function sign()
    {
        if ($this->smsType == 2) {
            $this->smsType = 1;
        }
        //        一些固定参数
        foreach ($this->config[$this->smsType] as $key => $v) {
            if ($key != 'Key') {
                $this->values[$key] = $v;
            }
        }
//        print_r($this->values);
        //签名步骤一：按字典序排序参数
        ksort($this->values);
        $buff = "";
        $noSignKey = array("Signature", "ContextParamSet", "TemplateParamSet", "SessionContextSet", "PhoneNumberSet", "SessionContext", "PhoneList", "phoneSet");
        foreach ($this->values as $k => $v) {
            if (!in_array($k, $noSignKey) && $v != "" && !is_array($v)) {
                $buff .= $k . "=" . $v . "&";
            }
        }
        $string = trim($buff, "&");
        //签名步骤二：在string后加入KEY
        $appKey = $this->config[$this->smsType]['Key'];
        $string = $string . "&key=" . $appKey;
        //签名步骤三：MD5加密或者HMAC-SHA256
        $string = md5($string);
        //签名步骤四：所有字符转为大写
        return strtoupper($string);
    }

    public function getSign($data = [])
    {
        foreach ($data as $key => $v) {
            $this->values[$key] = $v;
        }
        return $this->sign();
    }

    /**
     * 获取毫秒级别的时间戳
     */
    public static function getMillisecond()
    {
        //获取毫秒的时间戳
        $time = explode(" ", microtime());
        $time = $time[1] . ($time[0] * 1000);
        $time2 = explode(".", $time);
        return $time2[0];
    }


//通过已经审核好的模板发送，成功率高，速度快
    public function sendSmsByTpl($phone, $tplId, $tplType = 3, $tplContent = "", $tplParamsData = [])
    {
//        分析变量
        $tplParams = $this->parseTplParams($tplContent, $tplParamsData);
        $apiUrl = 'https://apis.shlianlu.com/sms/trade/template/send';
        if (empty($phone)) {
            return $this->returnMsg(1, '发送的手机号不能为空');
        }
        if (empty($tplId)) {
            return $this->returnMsg(2, '请正确填写已经审核通过的模板');
        }
        if ($tplType == 3) {
            $this->smsType = 3;
        } else {
            $this->smsType = 1;
        }
        if (!is_array($phone)) {
            $phone = explode(',', $phone);
        }
        $this->values['Type'] = 3;
        $this->values['PhoneNumberSet'] = $phone;
        $this->values['TemplateId'] = $tplId;
        $this->values['TemplateParamSet'] = $tplParams;

//        print_r($postData);

        $res = $this->requestSms($apiUrl);
//        return $this->returnMsg(15, 'f发送', $res);
//        print_r($res);
        if (intval($res['status']) === 0) {
            $data = [
                'smsId' => $res['taskId']
            ];
            return ['code' => 200, 'msg' => '发送成功', 'data' => $data];
        }
        return ['code' => -1, 'msg' => $res['message']];
    }

//发送短信,通过内容发送，这个可能会收不到，内容都要审核
    public function sendSms($phone, $content, $smsType = 3)
    {
        $apiUrl = 'https://apis.shlianlu.com/sms/trade/normal/send';
        if (empty($content)) {
            return $this->returnMsg(103, '发送的内容不能为空');
        }
        if (empty($phone)) {
            return $this->returnMsg(103, '发送的手机号不能为空');
        }
        $content = preg_replace("/【.+?】/", '', $content);
//        $content = "【" . $this->sendSignName . "】" . $content;
        if ($smsType == 3) {
//            短信模板类型 1、验证码，2、通知，3、营销
            $tplContent = $content . "拒收回R";
            $this->smsType = 3;
        }
        $this->values['Type'] = 1;
        $this->values['PhoneNumberSet'] = [$phone];
        $this->values['SignName'] = self::SignName;
        $this->values['SessionContext'] = $content;

//        print_r($postData);
        $res = $this->requestSms($apiUrl);
//        print_r($res);
        if (intval($res['status']) === 0) {
            $data = [
                'smsId' => $res['taskId']
            ];
            return ['code' => 200, 'msg' => '发送成功', 'data' => $data];
        }
        return ['code' => -1, 'msg' => $res['message']];
    }


//创建短信模版
    public function addTpl($tplName, $tplType, $tplContent)
    {
        if (empty($tplName) || empty($tplContent)) {
            return ['code' => -1, 'msg' => '模版内容缺少必要内容'];
        }
//        模板内容，营销短信，请带 退订回T（加上短信签名，不超过350个字符）
        $tplContent = preg_replace("/【.+?】/", '', $tplContent);
//        $tplContent = "【" . $this->sendSignName . "】" . $tplContent;
        if ($tplType == 3) {
//            短信模板类型 1、验证码，2、通知，3、营销
            $tplContent = $tplContent . "拒收回R";
            $this->smsType = 3;
        }
        $apiUrl = 'https://apis.shlianlu.com/sms/product/template/create';
        $this->values['SignId'] = self::SignId;
        $this->values['TemplateName'] = $tplName;
        $this->values['content'] = $tplContent;
        $res = $this->requestSms($apiUrl);
//        print_r($res);
        if (intval($res['status']) === 0) {
            $data = [
                'templateId' => $res['TemplateId']
            ];
            return ['code' => 200, 'msg' => '创建模版成功', 'data' => $data];
        }
        return ['code' => -1, 'msg' => $res['message']];
    }

//    修改模版内容
    public function editTpl($tplId, $tplName, $tplContent)
    {
        $apiUrl = 'https://apis.shlianlu.com/sms/product/template/update';
        $this->values['TemplateId'] = $tplId;
        $this->values['TemplateName'] = $tplName;
        $this->values['content'] = $tplContent;
        $res = $this->requestSms($apiUrl);
//        print_r($res);
        if (intval($res['status']) === 0) {
            return ['code' => 200, 'msg' => '修改模版成功', 'data' => $res];
        }
        return ['code' => -1, 'msg' => $res['message']];
    }

//    删除模版
    public function delTpl($tpl_id)
    {
        $apiUrl = 'https://apis.shlianlu.com/sms/product/template/delete';
        $this->values['TemplateId'] = $tpl_id;
        $res = $this->requestSms($apiUrl);
//        print_r($res);
        if (intval($res['status']) === 0) {
            return ['code' => 200, 'msg' => '删除模版成功', 'data' => $res];
        }
        return ['code' => -1, 'msg' => '删除模版失败'];
    }

//短信查询模板
    public function queryTpl($tpl_id = null)
    {
        if (empty($tpl_id)) {
            return ['code' => -1, 'msg' => '查询模版不能为空'];
        }
        $apiUrl = 'https://api.shlianlu.com/sms/product/template/getById';
        $this->values['TemplateId'] = $tpl_id;
        $res = $this->requestSms($apiUrl);
        if (intval($res['status']) === 0) {
//            统一的数据
//            print_r($res);
            $data = [
                'verifyStatus' => $res['data']['status'],
            ];
            return ['code' => 200, 'msg' => '查询模版成功', 'data' => $data];
        }
        return ['code' => -1, 'msg' => $res['message']];
    }

//    短信余额查询
    public function getBalance()
    {
        $apiUrl = 'https://apis.shlianlu.com/sms/product/balance';
        $res = $this->requestSms($apiUrl);
//        print_r($res);
        if (intval($res['status']) === 0) {
            $data = [
                'balance' => $res['balance']
            ];
            return ['code' => 200, 'msg' => '修改模版成功', 'data' => $data];
        }
        return ['code' => -1, 'msg' => $res['message']];
    }

    protected function requestSms($apiUrl)
    {
        $this->setSign();
//        print_r($this->values);
        $response = Http::withOptions([
//            'debug' => false,
            'timeout' => 30,
            'connect_timeout' => 30,
            'read_timeout' => 30
        ])->withHeaders([
            'Accept' => 'application/json',
            'Content-Type' => 'application/json;charset=utf-8'
        ])->post($apiUrl, $this->values);
        return $response->json();
    }

    public function returnMsg($code = 200, $msg = '', $data = [])
    {
        return [
            'code' => $code,
            'msg' => $msg,
            'data' => $data
        ];
    }
}
